Transactions and batch queries {prisma}

TODO

Transactions and batch queries 를 주의깊게 읽은 후 애그리거트가 지켜야 하는 트랜잭션 경계를 프리즈마를 사용하여 어떻게 달성할 수 있는지 알아봅시다.

Prisma가 우리 몰래 트랜잭션을 사용하는 경우

Can I use nested writes with bulk operations?

No - neither updateMany nor deleteMany currently supports nested writes. For example, you cannot delete multiple teams and all of their members (a cascading delete):

await prisma.team.deleteMany({
  where: {
    id: {
      in: [2, 99, 2, 11],
    },
  },
  data: {
    members: {}, // Cannot access members here
  },
})

우리가 명시적으로 $transaction([]) API를 사용하는 경우

UseCase: 여러 테이블에 걸친 Delete Operation

const id = 9 // User to be deleted

const deletePosts = prisma.post.deleteMany({
  where: {
    userId: id,
  },
})

const deleteMessages = prisma.privateMessage.deleteMany({
  where: {
    userId: id,
  },
})

const deleteUser = prisma.user.delete({
  where: {
    id: id,
  },
})

await prisma.$transaction([deletePosts, deleteMessages, deleteUser]) // Operations succeed or fail together

UseCase: pre-computed ID를 사용하고자 하는 경우

문서에서는 UUID를 사용하였으나, 내가 알기론 ObjectId도 애플리케이션 단에서 생성이 가능하다고 들었는데, 굳이 Nested Write를 사용하지 않고도 독립적인 오퍼레이션들로 분리한 다음 하나의 트랜잭션으로 실행하는 것도 적극적으로 도입해볼 수 있겠다.

import { v4 } from 'uuid'

const teamID = v4()
const userID = v4()

await prisma.$transaction([
  prisma.user.create({
    data: {
      id: userID,
      email: 'alice@prisma.io',
      team: {
        id: teamID,
      },
    },
  }),
  prisma.team.create({
    data: {
      id: teamID,
      name: 'Aurora Adventures',
    },
  }),
])